package com.party.web.biz.member;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.utils.DateUtils;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.YesNoStatus;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.PackageCount;
import com.party.core.model.message.MessageTag;
import com.party.core.model.notify.Event;
import com.party.core.model.notify.InstanceWay;
import com.party.core.model.notify.TargetTemplate;
import com.party.core.model.quartz.QuartzDataMap;
import com.party.core.model.system.TargetType;
import com.party.core.service.crowdfund.ITargetTemplateService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.member.IPackageCountService;
import com.party.core.service.notify.IEventService;
import com.party.core.service.quartz.IQuartzDataMapService;
import com.party.notify.notifyPush.servce.INotifyService;
import com.party.web.biz.quartz.IScheduleJobService;
import com.party.web.biz.quartz.impl.SchsduleService;
import com.party.web.utils.RealmUtils;
import com.party.web.web.dto.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.*;

/**
 * 行知公社--会员短信推送服务
 *
 * @Date: 2019/9/26 13:39
 */
@Service
public class MemberMgmtNotifyService {

    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ITargetTemplateService targetTemplateService;
    @Autowired
    private IPackageCountService packageCountService;
    @Autowired
    private IScheduleJobService scheduleJobService;
    @Autowired
    private INotifyService notifyService;
    @Autowired
    private IEventService eventService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberGroupService memberGroupService;
    @Autowired
    private IQuartzDataMapService quartzDataMapService;

    /**
     * 消息推送-定时
     *
     * @param targetTemplate
     * @param sendTimeString: 格式为yyyy-MM-dd HH:mm:ss
     * @param
     * @return
     */
    @Transactional
    public AjaxResult sendQuartz(TargetTemplate targetTemplate, String sendTimeString, String behavior, Integer type) {

        AjaxResult ajaxResult = new AjaxResult();
        Date date = null;
        if (StringUtils.isEmpty(sendTimeString)) {
            return AjaxResult.error("dateTime不能为空");
        }
        if (sendTimeString.indexOf(":") == sendTimeString.lastIndexOf(":")) {
            sendTimeString = sendTimeString + ":00";
        }
        try {
            date = DateUtils.parse(sendTimeString, "yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            logger.error("定时推送短信失败, 时间参数有误 dateTime = {}", sendTimeString, e);
            ajaxResult.setDescription("定时推送短信失败, 时间参数有误 dateTime = " + sendTimeString);
            ajaxResult.setSuccess(false);
            return ajaxResult;
        }

        // 定时的时间小于当前时间, 则直接立即执行
        if (date.getTime() < System.currentTimeMillis()) {
            if ("add".equals(behavior)) {
                this.sendAndSave(targetTemplate);
            } else if ("modifyTime".equals(behavior)) {
                return AjaxResult.error("时间参数有误, 该时间将永远不会执行 dateTime = " + sendTimeString);
            } else {
                this.send(targetTemplate.getId());
            }
            return AjaxResult.success();
        }

        targetTemplate.setSendTime(date);

        String tempId = null;
        boolean hasTemp;
        if ("add".equals(behavior)) {
            targetTemplate.setId(null);
            tempId = this.save(targetTemplate);
            hasTemp = false;
        } else {
            // 如果是修改发送时间, 需要检测该短信是否已经发送了
            if ("modifyTime".equals(behavior)) {
                TargetTemplate dbTemp = targetTemplateService.get(targetTemplate.getId());
                Date sendTime = dbTemp.getSendTime();
                if (null != sendTime && sendTime.getTime() < System.currentTimeMillis()) {
                    return AjaxResult.error("该短信已经发送了, 请刷新页面");
                }
            }
            targetTemplateService.update(targetTemplate);
            tempId = targetTemplate.getId();
            hasTemp = true;
        }

        if (StringUtils.isEmpty(tempId)) {
            return AjaxResult.error("保存定时发送短信模板失败, template = " + targetTemplate);
        }

        String cron = DateUtils.formatDate(date, "s m HH d M ? yyyy");

        final String clazz = "quartzBizSendShortMessage";
        final String method = "send";

        List<Object> params = Lists.newArrayList();
        params.add(type);

        Event event;
        if (hasTemp) {
            event = eventService.findByCode(clazz);
            event.setCronExpression(cron);
            scheduleJobService.dynamicUpdate(event, tempId, SchsduleService.GROUP_SEND_SHORT_MESSAGE, params);
        } else {
            event = new Event();
            event.setWay(com.party.common.constant.Constant.EVENT_AUTO);
            event.setName(SchsduleService.JOB_SEND_SHORT_MESSAGE);
            event.setCode(clazz);
            event.setType("4");
            event.setCronExpression(cron);
            event.setIsSync(0);
            event.setClassName(clazz);
            event.setMethod(method);
            scheduleJobService.dynamicInsert(event, tempId, SchsduleService.GROUP_SEND_SHORT_MESSAGE, params);
        }

        ajaxResult.setSuccess(true);

        return ajaxResult;
    }


    public String save(TargetTemplate targetTemplate) {
        if (Strings.isNullOrEmpty(targetTemplate.getTemplate())) {
            throw new BusinessException("模板内容不能为空");
        }
        if (Strings.isNullOrEmpty(targetTemplate.getMemberIds())) {
            throw new BusinessException("推送对象不能为空");
        }
        String memberId = RealmUtils.getCurrentUser().getId();
        //保存
        targetTemplate.setInitiatorId(memberId);
        targetTemplate.setMemberType(Constant.SEND_SHORT_MESSAGE_TYPE_MEMBER);
        return targetTemplateService.insert(targetTemplate);
    }

    /**
     * 发送消息and保存模板
     *
     * @param targetTemplate 目标模板
     */
    public boolean sendAndSave(TargetTemplate targetTemplate) {
        if (Strings.isNullOrEmpty(targetTemplate.getTemplate())) {
            throw new BusinessException("模板内容不能为空");
        }

        String memberId = RealmUtils.getCurrentUser().getId();
        //保存
        targetTemplate.setId(null);
        targetTemplate.setInitiatorId(memberId);
        Date now = new Date();
        targetTemplate.setCreateDate(now);
        targetTemplate.setUpdateDate(now);
        targetTemplate.setSendTime(now);
        targetTemplate.setMemberType(Constant.SEND_SHORT_MESSAGE_TYPE_MEMBER);
        targetTemplate.setTargetId(targetTemplate.getTargetId());
        targetTemplateService.insert(targetTemplate);

        return this.kcRealSend(targetTemplate, memberId);
    }

    /**
     * 发送消息and保存模板
     *
     * @param id 目标模板id
     */
    public boolean send(String id) {
        TargetTemplate targetTemplate = targetTemplateService.get(id);
        if (Strings.isNullOrEmpty(targetTemplate.getTemplate())) {
            throw new BusinessException("模板内容不能为空");
        }

        if (Strings.isNullOrEmpty(targetTemplate.getMemberIds())) {
            throw new BusinessException("推送对象不能为空");
        }

        String member = RealmUtils.getCurrentUser().getId();

        return this.kcRealSend(targetTemplate, member);
    }


    /**
     * 短信真实发送
     *
     * @param targetTemplate 模板
     * @param orgId          机构id
     */
    public boolean kcRealSend(TargetTemplate targetTemplate, String orgId) {
        PackageCount packageCount = packageCountService.getUnique(new PackageCount(orgId, TargetType.PUSH_SMS.getCode()));
        if (packageCount != null && YesNoStatus.YES.getCode().equals(packageCount.getIsOpen())) {
            Integer spareNum = packageCountService.getSpareNum(packageCount.getTotalNum(), packageCount.getUseNum());
            targetTemplate.setSpareNum(spareNum);
        }

        return this.send(orgId, targetTemplate, InstanceWay.ORGANIZATION.getName());
    }

    public boolean send(String authorId, TargetTemplate targetTemplate, String way) {
        String memberIds = targetTemplate.getMemberIds();
        List<String> memberIdList = new ArrayList<>();

        String[] strings = memberIds.split(",");
        for (String id : strings) {
            memberIdList.add(id);
        }

        boolean isCanFlag = this.packageCountService.checkSpareNum(targetTemplate, memberIdList.size());
        if (isCanFlag) {
            Iterator var7 = memberIdList.iterator();
            while (var7.hasNext()) {
                String kcmemberId = (String) var7.next();
                this.toPush(kcmemberId, authorId, targetTemplate, way);
            }
        }
        return isCanFlag;
    }

    public void toPush(String memberId, String authorId, TargetTemplate targetTemplate, String way) {

        MemberGroup parnetMember = memberGroupService.get(authorId);
        Member member = memberService.get(memberId);
        HashMap<String, Object> constant = Maps.newHashMap();
        constant.put("tag", MessageTag.UNDEFIND.getCode());
        constant.put("senderId", Strings.nullToEmpty(authorId));
        constant.put("way", way);
        constant.put("{partner}", Strings.nullToEmpty(parnetMember.getRealname()));
        constant.put("targetId", Strings.nullToEmpty(targetTemplate.getTargetId()));
        constant.put("templateId", targetTemplate.getId());

        this.notifyService.push("memberPush", member.getMobile(), authorId, constant, targetTemplate.getTemplate());
    }

    /**
     * 删除短信
     *
     * @param id: 模板id
     * @return
     */
    @Transactional
    public AjaxResult delQuartzForActivity(String id) {
        if (StringUtils.isEmpty(id)) {
            return AjaxResult.error("短信模板id不能为空");
        }
        TargetTemplate targetTemplate = targetTemplateService.get(id);
        if (null == targetTemplate) {
            return AjaxResult.error("找不到对应的模板 id= " + id);
        }
        // 移除定时器
        final String triggerName = SchsduleService.JOB_SEND_SHORT_MESSAGE.concat(SchsduleService.SEND_SHORT_MESSAGE_LINE).concat(id);
        final String group = SchsduleService.GROUP_SEND_SHORT_MESSAGE;
        scheduleJobService.removeTrigger(triggerName, group);
        // 删除短信
        targetTemplateService.delete(id);
        // 删除存的值在qrtz_data_map
        final String targetId = SchsduleService.PARAMS.concat(SchsduleService.SEND_SHORT_MESSAGE_LINE).concat(id);
        QuartzDataMap quartzDataMap = quartzDataMapService.findByTargetId(targetId);
        if (null != quartzDataMap) {
            quartzDataMapService.delete(quartzDataMap.getId());
        }
        return AjaxResult.success();
    }

}
